package com.example.teaching_server.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 侧边栏数据DTO
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "侧边栏完整数据")
public class SidebarDTO {

    @NotNull(message = "推荐数据不能为空")
    @Schema(description = "推荐内容数据", requiredMode = Schema.RequiredMode.REQUIRED)
    private RecommendationDTO recommendations;

    @NotNull(message = "新闻通知数据不能为空")
    @Schema(description = "新闻通知数据", requiredMode = Schema.RequiredMode.REQUIRED)
    private NewsNoticeDTO newsNotices;

    @NotNull(message = "日历数据不能为空")
    @Schema(description = "日历数据", requiredMode = Schema.RequiredMode.REQUIRED)
    private CalendarDTO calendar;

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "推荐内容数据")
    public static class RecommendationDTO {

        @NotBlank(message = "激活标签不能为空")
        @Schema(description = "当前激活的标签", example = "resources", allowableValues = {"resources", "activities"}, requiredMode = Schema.RequiredMode.REQUIRED)
        private String activeTab;

        @Schema(description = "资源推荐列表")
        private List<ResourceRecommendation> resourceRecommendations;

        @Schema(description = "活动推荐列表")
        private List<ActivityRecommendation> activityRecommendations;

        /**
         * 获取推荐总数
         */
        @Schema(description = "推荐总数", accessMode = Schema.AccessMode.READ_ONLY)
        public int getTotalRecommendations() {
            int count = 0;
            if (resourceRecommendations != null) count += resourceRecommendations.size();
            if (activityRecommendations != null) count += activityRecommendations.size();
            return count;
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "资源推荐信息")
    public static class ResourceRecommendation {

        @NotBlank(message = "推荐标题不能为空")
        @Schema(description = "推荐标题", example = "数学课件", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @Schema(description = "推荐描述", example = "高中数学第一章课件")
        private String description;

        @Schema(description = "图标名称", example = "Document")
        private String icon;

        @Schema(description = "跳转URL", example = "/resources/123")
        private String url;

        @Schema(description = "资源类型", example = "pdf", allowableValues = {"pdf", "doc", "video", "audio", "image"})
        private String type;

        @Schema(description = "推荐权重", example = "0.8")
        private Double weight;

        @Schema(description = "创建时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime createTime;

        /**
         * 获取类型图标
         */
        @Schema(description = "类型图标", accessMode = Schema.AccessMode.READ_ONLY)
        public String getTypeIcon() {
            if (type == null) return "QuestionFilled";
            return switch (type.toLowerCase()) {
                case "pdf" -> "Document";
                case "doc", "docx" -> "Document";
                case "video" -> "VideoPlay";
                case "audio" -> "Headphone";
                case "image" -> "Picture";
                default -> "QuestionFilled";
            };
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "活动推荐信息")
    public static class ActivityRecommendation {

        @NotBlank(message = "活动标题不能为空")
        @Schema(description = "活动标题", example = "数学竞赛", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @Schema(description = "活动时间", example = "14:00-16:00")
        private String time;

        @Schema(description = "图标名称", example = "Calendar")
        private String icon;

        @Schema(description = "跳转URL", example = "/activities/123")
        private String url;

        @Schema(description = "活动状态", example = "upcoming", allowableValues = {"upcoming", "ongoing", "completed"})
        private String status;

        @Schema(description = "活动地点", example = "教学楼201")
        private String location;

        /**
         * 判断是否为即将开始的活动
         */
        @Schema(description = "是否为即将开始的活动", accessMode = Schema.AccessMode.READ_ONLY)
        public boolean isUpcoming() {
            return "upcoming".equals(status);
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "新闻通知数据")
    public static class NewsNoticeDTO {

        @NotBlank(message = "激活标签不能为空")
        @Schema(description = "当前激活的标签", example = "news", allowableValues = {"news", "notices"}, requiredMode = Schema.RequiredMode.REQUIRED)
        private String activeTab;

        @Schema(description = "新闻列表")
        private List<NewsItem> newsItems;

        @Schema(description = "通知列表")
        private List<NoticeItem> notices;

        /**
         * 获取未读数量
         */
        @Schema(description = "未读数量", accessMode = Schema.AccessMode.READ_ONLY)
        public int getUnreadCount() {
            int count = 0;
            if (newsItems != null) {
                count += (int) newsItems.stream().filter(item -> !item.isRead()).count();
            }
            if (notices != null) {
                count += (int) notices.stream().filter(item -> !item.isRead()).count();
            }
            return count;
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "新闻项信息")
    public static class NewsItem {

        @NotBlank(message = "新闻标题不能为空")
        @Schema(description = "新闻标题", example = "学校举办科技创新大赛", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @Schema(description = "发布时间", example = "2小时前")
        private String time;

        @Schema(description = "新闻类型", example = "important", allowableValues = {"important", "normal"})
        private String type;

        @Schema(description = "跳转URL", example = "/news/123")
        private String url;

        @Schema(description = "是否已读", example = "false")
        private boolean read;

        @Schema(description = "新闻摘要")
        private String summary;

        /**
         * 判断是否为重要新闻
         */
        @Schema(description = "是否为重要新闻", accessMode = Schema.AccessMode.READ_ONLY)
        public boolean isImportant() {
            return "important".equals(type);
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "通知项信息")
    public static class NoticeItem {

        @NotNull(message = "通知ID不能为空")
        @Schema(description = "通知唯一标识", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
        private Long noticeId;

        @NotBlank(message = "通知标题不能为空")
        @Schema(description = "通知标题", example = "关于期末考试安排的通知", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @Schema(description = "通知内容")
        private String content;

        @Schema(description = "通知描述")
        private String description;

        @Schema(description = "通知类型名称", example = "系统通知")
        private String typeName;

        @Schema(description = "发送人姓名", example = "张老师")
        private String senderName;

        @Schema(description = "创建时间")
        private String createTime;

        @Schema(description = "显示时间", example = "今天 10:30")
        private String time;

        @Schema(description = "跳转URL", example = "/notices/123")
        private String url;

        @Schema(description = "是否已读", example = "false")
        private boolean read;

        @Schema(description = "是否紧急", example = "false")
        private boolean urgent;

        /**
         * 获取内容摘要
         */
        @Schema(description = "内容摘要", accessMode = Schema.AccessMode.READ_ONLY)
        public String getContentSummary() {
            if (content == null) return "";
            return content.length() > 50 ? content.substring(0, 50) + "..." : content;
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "日历数据")
    public static class CalendarDTO {

        @Pattern(regexp = "\\d{4}-\\d{2}", message = "月份格式应为YYYY-MM")
        @Schema(description = "选中的月份", example = "2024-03", requiredMode = Schema.RequiredMode.REQUIRED)
        private String selectedMonth;

        @Schema(description = "日历天数列表", requiredMode = Schema.RequiredMode.REQUIRED)
        private List<CalendarDay> calendarDays;

        @Schema(description = "本月事件总数")
        private Integer totalEvents;

        /**
         * 获取今天的日期
         */
        @Schema(description = "今天的日期", accessMode = Schema.AccessMode.READ_ONLY)
        public String getTodayDate() {
            return LocalDate.now().toString();
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "日历天数信息")
    public static class CalendarDay {

        @NotBlank(message = "日期不能为空")
        @Schema(description = "ISO格式日期", example = "2024-03-01", requiredMode = Schema.RequiredMode.REQUIRED)
        private String date;

        @Schema(description = "是否属于当前月份", example = "true", requiredMode = Schema.RequiredMode.REQUIRED)
        private boolean isCurrentMonth;

        @Schema(description = "是否是今天", example = "false", requiredMode = Schema.RequiredMode.REQUIRED)
        private boolean isToday;

        @Schema(description = "是否有事件", example = "true", requiredMode = Schema.RequiredMode.REQUIRED)
        private boolean hasEvent;

        @Schema(description = "事件数量", example = "2")
        private Integer eventCount;

        @Schema(description = "事件列表")
        private List<CalendarEvent> events;

        /**
         * 获取星期几
         */
        @Schema(description = "星期几", accessMode = Schema.AccessMode.READ_ONLY)
        public String getDayOfWeek() {
            try {
                LocalDate localDate = LocalDate.parse(date);
                return switch (localDate.getDayOfWeek()) {
                    case MONDAY -> "周一";
                    case TUESDAY -> "周二";
                    case WEDNESDAY -> "周三";
                    case THURSDAY -> "周四";
                    case FRIDAY -> "周五";
                    case SATURDAY -> "周六";
                    case SUNDAY -> "周日";
                };
            } catch (Exception e) {
                return "未知";
            }
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "日历事件信息")
    public static class CalendarEvent {
        private String title;
        private String time;
        private String type;
        private String color;
    }
}
